Language syntax

The syntax of M is similar to C-style languages like C++, Java or C#. It build on the same idea of expression and control flows like iteration and branching blocks but differs on the higher level abstractions. M does not contain any object oriented concepts like classes or visibility modifiers. Neither has the ability to specify new data structures using struct, enum or similar in C. Instead it provides two simple and powerful abstractions: Entities and systems.

There are two root level concepts in M: Entities and systems. In fact, every program written in M consists solely of entities and systems. The components of entities hold all the data of the program while systems hold the interactions.

Entities are defined by a name and a list of components. Each component holds a single value which might be a vector or an asset. Vectors store numeric values such as mass, position or rotation. They can have up to four dimensions. Assets are represented by a sequence of words of arbitrary length. The type inference system will decide which kind of asset - mesh, image, audio clip, font... - it is based on the usage of the component.

Systems are identified with a unique name and a list of sequential commands. These command can be blocks such as loops or branches that might in turn contain more commands themselves.

There are four kinds of commands. Loops iterate over entities with a certain constraints, branch commands take different paths depending of a condition. Repeat commands repeat their body a number of times. Assignments assign a value to a variable or a component. Call commands call a function that may be built in or defined by the user.

The expressions of the language consist of boolean and arithmetic expressions. Arithmetic expressions can use operands like +,-,,/,% and the bitwise &,|,<<,>>,^,~ to modify numerical values. The type of the operands must be compatible with the operation. The bitwise operators only work over single dimension vectors (scalars). The multiplicative operations ,/,% can take any vector as first argument but a scalar as a second argument. The additive operations + and - accept any two vectors as long as their dimensions are equal.

And that's it. More complex abstractions are built combining these basic concepts. You can watch some of these in action in the examples documentation.

Keywords

The grammar has some words reserved that can't be used as identifiers. The list of all identifiers is:

foreach, with, if, else

You can use any other word for your identifiers as long as it starts with an underscore or letter followed by any amount of letters and numbers.

Identifier: '_'? ('a'..'z'|'A'..'Z'|'0'..'9')+

White space. The parser of M ignores all the white space. You can structure your code as you want using white space. We recommend using the built in formatter for consistency across team members and easier version controlling.

Whitespace: '\n'|'\r'|' '|'\t'

Sometimes, the next token must be a number.

Number: '-'? DIGIT* ('.' DIGIT+ ('e' '-'? DIGIT+)?)?
DIGIT: '0'..'9'